package shake.context;

import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;

import shake.annotation.RedirectScoped;
import shake.event.EventAgent;
import shake.init.module.ComponentDescriptor;

import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
import com.google.inject.Singleton;

@Singleton
public class RedirectManager {
	AtomicInteger integer = new AtomicInteger();

	@Inject
	Provider<RedirectContext> redirectContext;

	@Inject
	Provider<HttpServletRequest> request;

	@Inject
	Logger logger;

	@Inject
	EventAgent aganet;

	@Inject
	ComponentRegistry reg;

	@Inject
	Injector injector;

	public Map<String, Object> restore(String id) {
		if (logger.isInfoEnabled()) {
			logger.info("resote redirect " + id);
		}
		if (id == null) {
			startup();
			return redirectContext.get().getMap();
		}

		Map<String, Object> s = (Map<String, Object>) request.get()
				.getSession().getAttribute(NAME + id);
		if (s != null) {
			request.get().getSession().removeAttribute(NAME + id);
			redirectContext.get().setMap(s);
			return s;
		} else {
			startup();
			return redirectContext.get().getMap();
		}

	}

	private void startup() {
		for (ComponentDescriptor desc : reg) {
			if (RedirectScoped.class.equals(desc.getScopeAnnotation())) {
				if (desc.isStartup()) {
					Object obj = injector.getInstance(desc.getKey());
					aganet.getStartup().fireEvent(obj);
				}
			}
		}
	}

	static final String NAME = "__R:";

	public String addRedirectid(String location) {
		int id = integer.incrementAndGet();
		request.get().getSession().setAttribute(NAME + id,
				redirectContext.get().getMap());
		if (location.contains("?")) {
			return location + "&redirect=" + id;
		} else {
			return location + "?redirect=" + id;
		}

	}

	public void destory(Map<String, Object> map) {
		for (ComponentDescriptor desc : reg) {
			if (RedirectScoped.class.equals(desc.getScopeAnnotation())) {
				Object obj = map.get(desc.getKey());
				if (obj != null) {
					aganet.getDestory().fireEvent(obj);
				}
			}
		}

	}

}
